/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Describe：实现Resources动态加载器的主要逻辑
* CreateTime：2020-04-05 21:40:40
* Version：1.0
* Modify Recorder：
*************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;

namespace TinyToolKit.AssetLoad
{
    public class ResourcesLoader : ResLoaderBase 
    {
        public ResourcesLoader()
        {
            assetsCache = new Dictionary<string, ResItem>();
        }

        public override ResItem LoadAsset(string resPath) 
        {
            ResItem resItem = new ResItem();
            if (assetsCache.TryGetValue(resPath,out resItem))
            {
                if (resItem.objs != null && resItem.objs.Length > 0)
                    return resItem;
            }

            resItem = new ResItem();
            Object obj = Resources.Load(resPath);
            if (obj != null)
            {
                resItem.objs = new Object[] { obj };
                if (assetsCache.ContainsKey(resPath) == false)
                    assetsCache.Add(resPath, resItem);
            }
            else
                TLogTool.Error("资源加载失败：" + resPath);
            return resItem;
        }

        public override ResItem LoadAsset<T>(string resPath)
        {
            ResItem resItem = new ResItem();
            if (assetsCache.TryGetValue(resPath, out resItem))
            {
                if (resItem.objs != null && resItem.objs.Length > 0)
                {
                    if (resItem.objs[0] is T)
                        return resItem;
                }
            }

            resItem = new ResItem();
            T obj = Resources.Load<T>(resPath);
            if (obj != null)
            {
                resItem.objs = new Object[] { obj };
                if (assetsCache.ContainsKey(resPath) == false)
                    assetsCache.Add(resPath, resItem);
            }
            else
                TLogTool.Error("资源加载失败：" + resPath);
            return resItem; 
        }

        public override void LoadAssetsAsync(string resPath, Type resType = null, Action<ResItem> callBack = null)
        {
            if (TinyTool.Instance != null)
                TinyTool.Instance.StartCoroutine(LoadResAsync(resPath, resType, callBack));
        } 
                                                                   
        public override ResItem LoadAllAssets(string resPath)
        {
            ResItem resItem; 
            if (assetsCache.TryGetValue(resPath, out resItem))
            {
                if (resItem.objs != null && resItem.objs.Length > 0)
                    return resItem;
            }

            resItem = new ResItem();
            Object[] objs = Resources.LoadAll(resPath);
            if (objs != null && objs.Length > 0)
            {
                resItem.objs = objs;
                if (assetsCache.ContainsKey(resPath) == false)
                    assetsCache.Add(resPath, resItem);
            }
            else
                TLogTool.Error("资源加载失败：" + resPath);
            return resItem;
        }

        public override ResItem LoadAllAssets<T>(string resPath)
        {
            ResItem resItem = new ResItem();
            if (assetsCache.TryGetValue(resPath, out resItem))
            {
                if (resItem.objs != null && resItem.objs.Length > 0)
                {
                    if (resItem.objs[0] is T)
                        return resItem;
                }
            }

            resItem = new ResItem();
            T[] objs = Resources.LoadAll<T>(resPath);
            if (objs != null && objs.Length > 0)
            {
                resItem.objs = objs;
                if (assetsCache.ContainsKey(resPath) == false)
                    assetsCache.Add(resPath, resItem);
            }
            else
                TLogTool.Error("资源加载失败：" + resPath);
            return resItem;
        }

        public override void UnloadUnusedAssets()  
        {
            assetsCache.Clear();  
            //要卸载掉GameObject的话，使用Resources.UnloadUnusedAssets()
            Resources.UnloadUnusedAssets();
        }

        public override void Clear()
        {
            assetsCache.Clear();
        }

        private IEnumerator LoadResAsync(string resPath, Type resType, Action<ResItem> callBack)
        {
            ResourceRequest request = resType != null ? Resources.LoadAsync(resPath, resType) : Resources.LoadAsync(resPath);
            yield return request;

            ResItem resItem = new ResItem();
            if (request.asset != null)
            {
                resItem.objs = new [] { request.asset };
                if (assetsCache.ContainsKey(resPath) == false)
                    assetsCache.Add(resPath, resItem);
            }
            else
                TLogTool.Error("资源加载失败：" + resPath);

            callBack?.Invoke(resItem);
        }
    }
}
